package com.ggh.config.Shiro;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ： jsq
 * @date ：2019/10/14 22:07
 * @description : 相关权限控制配置
 * @path : com.ggh.config.Shiro.ShiroConfig
 * @modifiedBy ：
 */
@Configuration
public class ShiroConfig {

   @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/notRole");
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<> ();
        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/wechatLogin", "anon");
       /**
        * 临时添加
        */
        filterChainDefinitionMap.put("/game", "anon");
        filterChainDefinitionMap.put("/**", "anon");

        //filterChainDefinitionMap.put("/", "anon");
        filterChainDefinitionMap.put("/front/**", "anon");
        filterChainDefinitionMap.put("/api/**", "anon");
        filterChainDefinitionMap.put("/api/**", "anon");
        filterChainDefinitionMap.put("/gamePKX/**", "anon");

        filterChainDefinitionMap.put("/admin/**", "authc");
        filterChainDefinitionMap.put("/user/**", "authc");
        //主要这行代码必须放在所有权限设置的最后，不然会导致所有 url 都被拦截 剩余的都需要认证
      //  filterChainDefinitionMap.put("/**", "authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;

    }
   @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * *
     * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     * *
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
     * * @return
     */
   // @Bean
   // @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }


        /**
         * SecurityManager 是 Shiro 架构的核心，通过它来链接Realm和用户(文档中称之为Subject.)
         */
        @Bean
        public SecurityManager securityManager() {
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            securityManager.setAuthenticator(modularRealmAuthenticator());

            List<Realm> realms = new ArrayList<>();
            // 用户密码登录realm
            realms.add(userPasswordRealm());
            // 微信登录realm
            realms.add(wechatLoginRealm());

            securityManager.setRealms(realms);
            return securityManager;
        }

        /**
         * 自定义的Realm管理，主要针对多realm
         */
        @Bean("myModularRealmAuthenticator")
        public MyModularRealmAuthenticator modularRealmAuthenticator() {
            MyModularRealmAuthenticator customizedModularRealmAuthenticator = new MyModularRealmAuthenticator();
            // 设置realm判断条件
            customizedModularRealmAuthenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());

            return customizedModularRealmAuthenticator;
        }


        /**
         * 密码登录realm
         *
         * @return
         */
        @Bean
        public UserPasswordRealm userPasswordRealm() {
            UserPasswordRealm userPasswordRealm = new UserPasswordRealm();
            userPasswordRealm.setName(LoginType.USER_PASSWORD.getType());
            return userPasswordRealm;
        }


        /**
         * 微信授权登录realm
         * @return
         */
        @Bean
        public WechatLoginRealm wechatLoginRealm(){
            WechatLoginRealm wechatLoginRealm = new WechatLoginRealm();
            wechatLoginRealm.setName(LoginType.WECHAT_LOGIN.getType());
            return wechatLoginRealm;
        }




}
